package cz.fimuni.pa165.backendderby.facade;

import cz.fimuni.pa165.backendapi.dto.CarDTO;
import cz.fimuni.pa165.backendapi.dto.CompanyDTO;
import cz.fimuni.pa165.backendapi.dto.EmployeeDTO;
import cz.fimuni.pa165.backendapi.dto.RequestDTO;
import cz.fimuni.pa165.backendapi.dto.ReservationDTO;
import cz.fimuni.pa165.backendapi.facade.ServiceFacade;
import cz.fimuni.pa165.backendderby.entities.Car;
import cz.fimuni.pa165.backendderby.entities.Company;
import cz.fimuni.pa165.backendderby.entities.Employee;
import cz.fimuni.pa165.backendderby.entities.Reservation;
import cz.fimuni.pa165.backendderby.services.CarService;
import cz.fimuni.pa165.backendderby.services.CompanyService;
import cz.fimuni.pa165.backendderby.services.EmployeeService;
import cz.fimuni.pa165.backendderby.services.ReservationService;
import java.util.ArrayList;
import java.util.List;
import org.dozer.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;

@Service
public class ServiceFacadeImpl implements ServiceFacade {

    @Autowired
    private CarService carService;
    @Autowired
    private CompanyService companyService;
    @Autowired
    private EmployeeService employeeService;
    @Autowired
    private ReservationService reservationService;
    @Autowired
    private Mapper mapper;

    @Override
    @PreAuthorize("hasAnyRole('ROLE_ADMIN')")
    public void addCar(CarDTO c) {
        carService.createCar(mapper.map(c, Car.class));
    }

    @Override
    @PreAuthorize("hasAnyRole('ROLE_ADMIN')")
    public void updateCar(CarDTO c) {
        carService.updateCar(mapper.map(c, Car.class));
    }

    @Override
    @PreAuthorize("hasAnyRole('ROLE_ADMIN')")
    public void removeCar(CarDTO c) {
        carService.deleteCar(mapper.map(c, Car.class));
    }

    @Override
    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    public List<CarDTO> getAllCars() {
        List<Car> allAvailibleCars = carService.getAllCars();
        List<CarDTO> list = new ArrayList<CarDTO>();
        for (int i = 0; i < allAvailibleCars.size(); i++) {
            list.add(mapper.map(allAvailibleCars.get(i), CarDTO.class));
        }
        return list;
    }

    @Override
    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    public List<CarDTO> processRequest(RequestDTO request) {
        List<Car> list = carService.processRequest(request);
        List<CarDTO> result = new ArrayList<CarDTO>();
        for (int i = 0; i < list.size(); i++) {
            CarDTO carDTO = mapper.map(list.get(i), CarDTO.class);
            result.add(carDTO);
        }
        return result;
    }

    @Override
    @PreAuthorize("hasAnyRole('ROLE_ADMIN')")
    public void addCompany(CompanyDTO c) {
        Company company = mapper.map(c, Company.class);
        companyService.createCompany(company);
    }

    @Override
    @PreAuthorize("hasAnyRole('ROLE_ADMIN')")
    public void removeCompany(CompanyDTO c) {
        Company company = mapper.map(c, Company.class);
        companyService.removeCompany(company);
    }

    @Override
    @PreAuthorize("hasAnyRole('ROLE_ADMIN')")
    public boolean updateCompany(CompanyDTO c) {
        Company company = mapper.map(c, Company.class);
        return companyService.updateCompany(company);
    }

    @Override
    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    public List<CompanyDTO> getAllCompanies() {
        List<Company> list = companyService.findAllCompanies();
        List<CompanyDTO> result = new ArrayList<CompanyDTO>();
        if (list != null) {
            for (int i = 0; i < list.size(); i++) {
                CompanyDTO compDTO = mapper.map(list.get(i), CompanyDTO.class);
                result.add(compDTO);
            }
        }
        return result;
    }

    @Override
    @PreAuthorize("hasAnyRole('ROLE_ADMIN')")
    public void addEmployee(EmployeeDTO empDTO) {
        Employee emp = mapper.map(empDTO, Employee.class);
        employeeService.createEmployee(emp);
    }

    @Override
    @PreAuthorize("hasAnyRole('ROLE_ADMIN')")
    public void removeEmployee(EmployeeDTO empDTO) {
        Employee emp = mapper.map(empDTO, Employee.class);
        employeeService.deleteEmployee(emp);
    }

    @Override
    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    public void updateEmployee(EmployeeDTO empDTO) {
        Employee emp = mapper.map(empDTO, Employee.class);
        employeeService.updateEmployee(emp);
    }

    @Override
    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    public EmployeeDTO getEmployeeById(Long id) {
        EmployeeDTO empDTO = mapper.map((employeeService.get(id)), EmployeeDTO.class);
        return empDTO;
    }

    @Override
    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    public List<EmployeeDTO> getAllEmployees() {
        List<Employee> employees = employeeService.getAllEmployees();
        List<EmployeeDTO> result = new ArrayList<EmployeeDTO>();
        for (int i = 0; i < employees.size(); i++) {
            EmployeeDTO empDTO = mapper.map(employees.get(i), EmployeeDTO.class);
            result.add(empDTO);
        }
        return result;
    }

    @Override
    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    public List<EmployeeDTO> findEmployeeByName(String surname) {
        List<Employee> employees = employeeService.findByName(surname);
        List<EmployeeDTO> result = new ArrayList<EmployeeDTO>();
        for (int i = 0; i < employees.size(); i++) {
            EmployeeDTO empDTO = mapper.map(employees.get(i), EmployeeDTO.class);
            result.add(empDTO);
        }
        return result;
    }
    
    @Override
    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    public List<EmployeeDTO> findEmployeeByUsername(String username) {
        List<Employee> employees = employeeService.findByUsername(username);
        List<EmployeeDTO> result = new ArrayList<EmployeeDTO>();
        for (int i = 0; i < employees.size(); i++) {
            EmployeeDTO empDTO = mapper.map(employees.get(i), EmployeeDTO.class);
            result.add(empDTO);
        }
        return result;
    }

    @Override
    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    public List<EmployeeDTO> findEmployeesByCompany(CompanyDTO compDTO) {
        Company temp = mapper.map(compDTO, Company.class);
        List<Employee> employees = employeeService.findByCompany(temp);
        List<EmployeeDTO> result = new ArrayList<EmployeeDTO>();
        for (int i = 0; i < employees.size(); i++) {
            EmployeeDTO empDTO = mapper.map(employees.get(i), EmployeeDTO.class);
            result.add(empDTO);
        }
        return result;
    }

    @Override
    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    public void addReservation(ReservationDTO res) throws IllegalArgumentException {
        reservationService.create(mapper.map(res, Reservation.class));
    }

    @Override
    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    public List<ReservationDTO> getReservationByEmployee(EmployeeDTO empl) {
        List<Reservation> reservations = reservationService.get(mapper.map(empl, Employee.class));
        List<ReservationDTO> reservationsDTO = new ArrayList<ReservationDTO>();
        for (int i = 0; i < reservations.size(); i++) {
            ReservationDTO resDTO = mapper.map(reservations.get(i), ReservationDTO.class);
            reservationsDTO.add(resDTO);
        }
        return reservationsDTO;
    }

    @Override
    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    public ReservationDTO getByID(Long id) {
        ReservationDTO resDTO = mapper.map(reservationService.getByID(id), ReservationDTO.class);
        return resDTO;
    }

    @Override
    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    public void removeReservation(ReservationDTO res) {
        reservationService.remove(mapper.map(res, Reservation.class));
    }

    @Override
    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    public CompanyDTO getCompanyById(Long id) {
        Company comp = companyService.findCompany(id);
        if (comp == null) {
            return null;
        } else {
            CompanyDTO comDTO = mapper.map(comp, CompanyDTO.class);
            return comDTO;
        }

    }

    @Override
    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_USER')")
    public List<ReservationDTO> getAllReservations() {
        List<Reservation> reservs = reservationService.getAllReservations();
        List<ReservationDTO> result = new ArrayList<ReservationDTO>();
        for (int i = 0; i < reservs.size(); i++) {
            ReservationDTO resDTO = mapper.map(reservs.get(i), ReservationDTO.class);
            result.add(resDTO);
        }
        return result;
    }

    public CarDTO find(Long id) {
        Car car = carService.find(id);
        if (car == null) {
            return null;
        } else {
            CarDTO carDto = mapper.map(car, CarDTO.class);
            return carDto;
        }
    }
}
